package com.example.schoolexam2.service.impl;

import cn.hutool.core.util.IdUtil;
import com.example.schoolexam2.dto.StudentChooseDto;
import com.example.schoolexam2.entity.*;
import com.example.schoolexam2.mapper.EmplMapper;
import com.example.schoolexam2.mapper.ExamMapper;
import com.example.schoolexam2.mapper.QuestionMapper;
import com.example.schoolexam2.service.ExamService;
import com.example.schoolexam2.utils.PageUtils;
import com.example.schoolexam2.utils.QuestionAboutUtil;
import com.example.schoolexam2.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
public class ExamServiceImpl implements ExamService {
    /**
     * 创建考试
     */
    @Autowired
    ExamMapper examMapper;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    EmplMapper emplMapper;

    PageUtils pageUtils=new PageUtils();
    /**
     * 保存试卷
     *
     * @param createVo
     */
    @Override
    public void createExam(ExamCreateVo createVo) {
        Exam exam = new Exam();
        BeanUtils.copyProperties(createVo, exam); //将中间体的属性拷贝给实体
        String examId = IdUtil.simpleUUID();
        exam.setExamId(examId); //设置考试的id后保存
        //TODO exam实体需要一个teacherId， 需要一个班级id，来作为试卷和学生的关联，后期应该是一个班级数组
        exam.setTeacherId("202000030579");
        exam.setDepartmentId("17");

        examMapper.createExam(exam);

        //将试卷和班级关联起来
//        String[] clazzIds = createVo.getClazzIds();
//        for (String clazzId : clazzIds) {
//            examMapper.saveExamAndClazz(clazzId,examId);
//        }
        examMapper.saveExamAndClazz("1",examId);
        examMapper.saveExamAndClazz("2",examId);

        //把题目保存到关联的表中
        List<QuestionRadioVo> radioVoList = createVo.getRadioVoList();
        for (QuestionRadioVo questionRadioVo : radioVoList) { //保存单选题
            examMapper.saveEIdAndQId(examId, questionRadioVo.getQuestionId(), questionRadioVo.getQuestionScore(), "1");
            //将被选中的试题的属性改变
            questionMapper.changeChooseRadio(questionRadioVo.getQuestionId());
        }
        List<QuestionCheckdVo> checkdVoList = createVo.getCheckdVoList();
        for (QuestionCheckdVo questionCheckdVo : checkdVoList) {
            examMapper.saveEIdAndQId(examId, questionCheckdVo.getQuestionId(), questionCheckdVo.getQuestionScore(), "2");
            questionMapper.changeChooseCheckd(questionCheckdVo.getQuestionId());
        }
        List<QuestionFillVo> fillVoList = createVo.getFillVoList();
        for (QuestionFillVo questionFillVo : fillVoList) {
            examMapper.saveEIdAndQId(examId, questionFillVo.getQuestionId(), questionFillVo.getQuestionScore(), "3");
            questionMapper.changeChooseFill(questionFillVo.getQuestionId());
        }
        List<QuestionJudgeVo> judgeVoList = createVo.getJudgeVoList();
        for (QuestionJudgeVo questionJudgeVo : judgeVoList) {
            examMapper.saveEIdAndQId(examId, questionJudgeVo.getQuestionId(), questionJudgeVo.getQuestionScore(), "4");
            questionMapper.changeChooseJudge(questionJudgeVo.getQuestionId());
        }

    }

    /**
     * 根据班级信息获取当前班级的考试
     */
    @Override
    public List<Exam> getOwnAllExam(String classInfo) {
        List<String> examIds = examMapper.findExamByClassInfo(classInfo);
        List<Exam> exams = new ArrayList<>();
        for (String examId : examIds) {
            exams.add(examMapper.findExamById(examId));
        }
        return exams;

    }

    /**
     * 根据试卷id查询试卷所有信息
     */
    @Override
    public ExamVo getExam(String examId) {
        //判断学生是否做古此试卷，做过的话此方法就查询

        ExamVo examListVo = new ExamVo();
        //通过试卷id查询到试卷实体
        Exam examById = examMapper.findExamById(examId);
        //将实体属性拷贝给vo对象
        BeanUtils.copyProperties(examById, examListVo);

        //通过试卷id查询试卷的所有题目的id，并获得试题对象并封装
        //单选
        int allScore = 0;
        List<Map<String,String>> ridAndScores = examMapper.findRadioIdByExamId(examId);
        List<QuestionRadio> radios = new ArrayList<>();
        for (Map<String,String> radioId : ridAndScores) {
            QuestionRadio radio = questionMapper.findRadioById(radioId.get("questionId"));
            int score = Integer.parseInt(radioId.get("questionScore"));
            allScore += score;
            radio.setQuestionScore(score); //设置当前题目在此试卷的分数
            radios.add(radio);
        }
//        examListVo.setRadioList(radios);  封装到vo实体
        //多选
        List<Map<String,String>> cidAndScores = examMapper.findCheckdIdByExamId(examId);
        List<QuestionCheckd> checkds = new ArrayList<>();
        for (Map<String,String> checkId : cidAndScores) {
            QuestionCheckd check = questionMapper.findCheckdById(checkId.get("questionId"));
            int score = Integer.parseInt(checkId.get("questionScore"));
            allScore += score;
            check.setQuestionScore(score);
            checkds.add(check);
        }
//        examListVo.setCheckdList(checkds);  封装到vo实体
        //填空
        List<Map<String,String>> fidAndScores = examMapper.findFillIdByExamId(examId);
        List<QuestionFill> fills = new ArrayList<>();
        for (Map<String,String> fillId : fidAndScores) {
            QuestionFill fill = questionMapper.findFillById(fillId.get("questionId"));
            int score = Integer.parseInt(fillId.get("questionScore"));
            allScore += score;
            fill.setQuestionScore(score);
            fills.add(fill);
        }
//        examListVo.setFillList(fills); 封装到vo实体
        //判读
        List<Map<String,String>> jidAndScores = examMapper.findJudgeIdByExamId(examId);
        List<QuestionJudge> judges = new ArrayList<>();
        for (Map<String,String> judgeId : jidAndScores) {
            QuestionJudge judge = questionMapper.findJudgeById(judgeId.get("questionId"));
            int score = Integer.parseInt(judgeId.get("questionScore"));
            allScore += score;
            judges.add(judge);
        }
        //通过工具方法，将试题转换成前端需要的形式
        TestVO trans = QuestionAboutUtil.trans(radios, checkds, fills, judges);
        //将各种数据封装到要返回的vo中
        examListVo.setRadioList(trans.getRadios());
        examListVo.setCheckdList(trans.getCheckds());
        examListVo.setFillList(trans.getFills());
        examListVo.setJudgeList(trans.getJudges());
        examListVo.setExamScore(allScore);
        return examListVo;
    }

    /**
     * 通过学生id和考试id查询学生当前试卷的作答情况
     *
     * @param studentId
     * @param examId
     * @return
     */
    @Override
    public ExamVo getStudentChoose(String studentId, String examId) {
        /*
        通过试卷id获取当前试卷的所有信息，得到试题集合，
        再通过保存学生操作的表插叙学生对当前表的操作
         */
        ExamVo exam = getExam(examId);
        //单选
        List<QuestionRadioListVo> radioList = exam.getRadioList();
        for (QuestionRadioListVo questionRadioListVo : radioList) {
            String studentChoose = questionMapper.getStudentChoose(studentId, examId, "1", questionRadioListVo.getQuestionId());
            if (studentChoose != null) {
                QuestionOptionListVo[] options = questionRadioListVo.getOptions();
                switch (studentChoose) {
                    case "1":
                        options[0].setQuestionIsChoose(true);//学生选a
                        break;
                    case "2":
                        options[1].setQuestionIsChoose(true);
                        break;
                    case "3":
                        options[2].setQuestionIsChoose(true);
                        break;
                    case "4":
                        options[3].setQuestionIsChoose(true);
                }
            } else {
                continue;
            }
        }
        //多选题
        List<QuestionCheckdListVo> checkdList = exam.getCheckdList();
        for (QuestionCheckdListVo questionCheckdListVo : checkdList) {
            String studentChoose = questionMapper.getStudentChoose(studentId, examId, "2", questionCheckdListVo.getQuestionId());
            if (studentChoose != null) {
                String[] split = studentChoose.split("-");
                QuestionOptionListVo[] options = questionCheckdListVo.getOptions();
                for (String s : split) {
                    switch (s) {
                        case "1":
                            options[0].setQuestionIsChoose(true);//学生选a
                            break;
                        case "2":
                            options[1].setQuestionIsChoose(true);
                            break;
                        case "3":
                            options[2].setQuestionIsChoose(true);
                            break;
                        case "4":
                            options[3].setQuestionIsChoose(true);
                    }
                }
            } else {
                continue;
            }
        }
        //填空题
        List<QuestionFillListVo> fillList = exam.getFillList();
        for (QuestionFillListVo questionFillListVo : fillList) {
            String studentChoose = questionMapper.getStudentChoose(studentId, examId, "3", questionFillListVo.getQuestionId()); //填空题如果学生填写了就保存的是学生填写的答案
            if (studentChoose != null) {
                //学生当前题目做了选择
                QuestionOptionListVo[] options = questionFillListVo.getOptions();
                options[0].setQuestionOption(studentChoose);
                options[0].setQuestionIsChoose(true);
            }
        }
        //判断题
        List<QuestionJudgeListVo> judgeList = exam.getJudgeList();
        for (QuestionJudgeListVo questionJudgeListVo : judgeList) {
            String studentChoose = questionMapper.getStudentChoose(studentId, examId, "4", questionJudgeListVo.getQuestionId());
            QuestionOptionListVo[] options = questionJudgeListVo.getOptions();
            if (studentChoose != null) {
                switch (studentChoose) {
                    case "1":
                        options[0].setQuestionIsChoose(true);
                        break;
                    case "2":
                        options[1].setQuestionIsChoose(true);
                        break;
                }
            }
        }
        int studentScore = examMapper.getStudentScore(studentId, examId);
        exam.setExamScore(studentScore);
        return exam;
    }

    /**
     * 保存学生对当前试卷的操作
     */
    @Override
    public void saveStudentChoose(StudentChooseDto chooseDto) {
        try {
            questionMapper.delStudentOldChoose(chooseDto.getStudentId());
        } catch (Exception e) {
            System.out.println("当前学生没有保存记录");
        }
        String studentId = chooseDto.getStudentId();
        String examId = chooseDto.getExamId();
        //保存单选题
        List<QuestionRadioListVo> radioList = chooseDto.getRadioList();
        if (radioList!=null){
            for (QuestionRadioListVo questionRadioListVo : radioList) {
//            int questionScore = questionRadioListVo.getQuestionScore();
//            studentScore += questionScore;
                QuestionOptionListVo[] options = questionRadioListVo.getOptions();
                for (int i = 0; i < options.length; i++) {
                    if (options[i].getQuestionIsChoose()) { //当前选项被选中，
                        questionMapper.saveStudentChoose(studentId, examId, questionRadioListVo.getQuestionId(), "1", String.valueOf(i));
                    }
                }
            }
        }
        //保存多选题
        List<QuestionCheckdListVo> checkdList = chooseDto.getCheckdList();
        if (checkdList !=null){
            for (QuestionCheckdListVo questionCheckdListVo : checkdList) {
//            int questionScore = questionCheckdListVo.getQuestionScore();
//            studentScore += questionScore;
                QuestionOptionListVo[] options = questionCheckdListVo.getOptions();
                StringBuffer temp = new StringBuffer(); //临时存储学生选择的字符串
                for (int i = 0; i < options.length; i++) {
                    if (options[i].getQuestionIsChoose()) {//学生选择了当前选项
                        temp.append("-" + i);
                    }
                }
                System.out.println(temp);
                if (temp != null) {  //学生对当前题有操作
                    String substring = temp.substring(1);
                    questionMapper.saveStudentChoose(studentId, examId, questionCheckdListVo.getQuestionId(), "2", substring);
                }
            }
        }
        //保存填空题
        List<QuestionFillListVo> fillList = chooseDto.getFillList();
        if (fillList!=null){
            for (QuestionFillListVo questionFillListVo : fillList) {
//            int questionScore = questionFillListVo.getQuestionScore();
//            studentScore += questionScore;
                QuestionOptionListVo[] options = questionFillListVo.getOptions();
//            if (options[0].getQuestionIsChoose()) { //学生填了当前题目
//                questionMapper.saveStudentChoose(studentId, examId, questionFillListVo.getQuestionId(), "3", options[1].getQuestionOption());
//            }
                StringBuffer stringBuffer = new StringBuffer();
                for (int i = 0; i < options.length; i++) { //对各个空进行循环，如果有填就保存操作
                    if (options[i].getQuestionIsChoose()) {//学生填了当前空
                        stringBuffer.append("-" + options[i].getQuestionOption());
                    }
                }
                System.out.println(stringBuffer);
                if (stringBuffer.length()>0){
                    String substring = stringBuffer.substring(1);
                    questionMapper.saveStudentChoose(studentId,examId,questionFillListVo.getQuestionId(),"3",substring)          ;
                }
            }
        }
        //保存判断题
        List<QuestionJudgeListVo> judgeList = chooseDto.getJudgeList();
        if (judgeList!=null){
            for (QuestionJudgeListVo questionJudgeListVo : judgeList) {
//            int questionScore = questionJudgeListVo.getQuestionScore();
//            studentScore += questionScore;
                QuestionOptionListVo[] options = questionJudgeListVo.getOptions();
                for (int i = 0; i < options.length; i++) {
                    if (options[i].getQuestionIsChoose()) {
                        questionMapper.saveStudentChoose(studentId, examId, questionJudgeListVo.getQuestionId(), "4", String.valueOf(i));
                    }
                }
            }
            if (chooseDto.getIsCommit()) { //当前请求是提交，保存分数
                examMapper.saveScore(studentId, examId, chooseDto.getTotalScore());
            }
        }

    }

    /**
     * 将问题实体转换成前台需要的形式并返回
     *
     * @return
     */
    @Override
    public TestVO test() {
        List<QuestionRadio> allRadio1 = questionMapper.findAllRadio1();
        List<QuestionCheckd> allCheckd1 = questionMapper.findAllCheckd1();
        List<QuestionFill> allFill1 = questionMapper.findAllFill1();
        List<QuestionJudge> allJudge1 = questionMapper.findAllJudge1();
        return QuestionAboutUtil.trans(allRadio1, allCheckd1, allFill1, allJudge1);
    }

    /**
     * 学生获取历史试卷
     * @param studentId
     * @return
     */
    @Override
    public List<ExamVo> getHistoryExam(String studentId) {
        List<Map<String, String>> maps = examMapper.selectHostoryExam(studentId);
        List<ExamVo> results=new ArrayList<>();
        for (Map<String, String> map : maps) {
            //获取试卷id查询试卷实体
            Exam examId = examMapper.findExamById(map.get("examId"));
            ExamVo examListVo = new ExamVo();
            BeanUtils.copyProperties(examId,examListVo);
            examListVo.setExamScore(Integer.parseInt(map.get("score")));
            results.add(examListVo);
        }
        return results;
    }

    @Override
    public PageVo teacherGetExam(String departmentId, String isPublic, String teacherId,String examName, int currentpage, int size) {
        int examCount = examMapper.findExamCount(departmentId, isPublic, teacherId, examName);
        PageVo page = pageUtils.page(examCount, currentpage, size);
        page.setData(Collections.singletonList(examMapper.findExam(departmentId, isPublic, teacherId, examName, page.getStartCount(), page.getSize())));
        return page;
    }


}
